import math
import random


def randomOP1(t):
    return t + random.gauss(0.0, 1.0)

class DamageModel:
    def __init__(self, v0, m, k, operator, scale=1.0):
        self.m = m
        self.v0 = v0
        self.k = k
        self.op = operator
        self.scale = scale
        
    def __call__(self, g, level):
        g = -g
        v = (-(self.m * g)/self.k + (self.v0 + (self.m * g)/self.k)*math.e**(-self.k*level/self.m))*self.scale
        return self.op(v)

#Let's just stick the weapno particle types here for now. 
class WeaponSystemTypes:
    COUNT=2
    LASERAT419, LASERNBMAX=range(COUNT)
    MATERIALS=["BTFX/AttackParticleLaserA", "BTFX/AttackParticleLaserB"]
    SOUNDFX=["Laser_SHOOT2.wav", "Laser_SHOOT.wav"]

class ResolveCombat:
    @staticmethod
    def resolve(weapon, defense, attackerAttributes, attackerStats, defenderAttributes, defenderStats):
        weapDamage = weapon.getDamage(attackerAttributes, attackerStats)
        protect = defense.getProtect(defenderAttributes, defenderStats)
        damage = weapDamage - protect
        if int(damage) < 0:
            damage = 0
        return damage
            
"""
Implement something simple and quick for testing. I need to think about how the combat system works.
"""
class WeaponSystem: 
    """
    This should be abstract class. Not familiar with python
    """
    def __init__(self, systemid, level, damage=1, rate=5.0, accuracy=0.8, speed=1.0):
        self.damage = damage
        self.rate = rate
        self.speed = speed #units in meters
        self.accuracy=accuracy
        self.weaponSystemId = systemid
        self.baseDPS = float(damage) / rate
        self.level = level
    def getAttackDamage(self, attackerAttributes, defenderAttributes):
        raise NotImplementedError("Abstract Base Class")

class LaserWeapons(WeaponSystem):
    def __init__(self, systemid, level, damage, rate, accuracy=1.0, speed=500.0):
        WeaponSystem.__init__(self, systemid, level, damage, rate, accuracy, speed)
        if systemid == 0:
            self.speed = 100.0 
        self.weaponModel = DamageModel(0.0, 1.0, 0.5, randomOP1)
        
    def getDamage(self, attackerAttributes, attackerStats):
        dmg = self.baseDPS + self.weaponModel(attackerAttributes.power, attackerStats.level)
        return dmg

class DefenseSystem:
    """
    Defense system encapsulates the concept of defensive tools. It is coupled with
    the attribute system to form the defensive system.
    """
    def __init__(self, protectValue):
        self.protect = protectValue
        
    def getProtect(self):
        raise NotImpelentedError ("Abstract Base Class")

class ArmorSystem(DefenseSystem):
    
    def __init__(self, protectValue):
        DefenseSystem.__init__(self, protectValue)

    def getProtect(self, defenderAttributes, defenderStats):
        return self.protect

class RandomWeaponAndArmor:
    @staticmethod
    def getWeapon(level, range, id=-1):
        if id < 0:
            typeid = random.randint(0, 1)
        else:
            typeid = id
        rate = [1.0, 2.0, 1.5]
        basedamage = 10.0  + level
        #we will implement a more random system soon.
        weapon = LaserWeapons(typeid, level, basedamage + random.randint(range[0], range[1]), rate=rate[random.randint(0, 2)])
        return weapon
    @staticmethod
    def getArmor(level):
        armor = ArmorSystem(6.0 + level)
        return armor

        